package com.xx.Tab;

import com.xx.util.Util;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.event.Event;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.*;
import javafx.scene.effect.ColorAdjust;
import javafx.scene.effect.ColorInput;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.ClipboardContent;
import javafx.scene.input.Dragboard;
import javafx.scene.input.TransferMode;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;

import java.util.Objects;

import static com.xx.Tab.FXBDTabPane.*;


public  class FXBDTab {
        final StackPane content;
        private final SimpleStringProperty info = new SimpleStringProperty();
        private final HBox title = new HBox(10);
//        记录上一个展示的tab.
        private FXBDTab lastTab;
        private final Image item;
//        有可能会换展示的tabPane,将oldTabPane记录下来修改数据.
        private FXBDTabPane oldTabPane;
        FXBDTabPane tabPane;
        SimpleBooleanProperty isDraga = new SimpleBooleanProperty(false);
        private SimpleBooleanProperty isShow = new SimpleBooleanProperty(false);
        public FXBDTab(StackPane content, String info, Image item,FXBDTabPane tabPane) {
            this.content = content;
            this.info.set(info);
            this.item = item;
            init(item);
            initDraga();
            this.tabPane = tabPane;
        }
        public FXBDTab(FXBDTab tab,FXBDTabPane tabPane){
            this(tab.content,tab.info.get(),tab.item,tabPane);
        }
        private void init(Image item){
            title.setAlignment(Pos.CENTER);
            title.setMinSize(0,0);
            title.setBackground(new Background(new BackgroundFill(Color.WHITE,null, null)));
            ImageView imageView = new ImageView(item);
            imageView.setPreserveRatio(true);
            imageView.setFitWidth(50);


            Label close = new Label();
            close.setVisible(false);
            close.setContentDisplay(ContentDisplay.TEXT_ONLY);
            close.setPrefSize(50,50);
            close.setText("X");
            close.setFont(Font.font(30));
            close.setAlignment(Pos.CENTER);
            close.setBackground(new Background(new BackgroundFill(Color.WHITE,null, null)));
            ColorAdjust adjust = new ColorAdjust();
            close.setEffect(adjust);
            close.hoverProperty().addListener((ob,ov,nv)->adjust.setBrightness(nv?0.6:0));
            close.setOnMouseClicked(event -> {
                tabPane.closeTab(this);
                event.consume();
            });
            close.setOnMousePressed(Event::consume);
            title.hoverProperty().addListener((ob,ov,nv)->{
                if (!isShow.get()) close.setVisible(nv);
            });
            isShow.addListener((ob,ov,nv)->close.setVisible(nv));

            Text text = new Text();
            text.textProperty().bind(info);
            HBox hb = new HBox(text);
            hb.setAlignment(Pos.CENTER_LEFT);
            hb.setMinSize(0,0);

            title.getChildren().addAll(imageView,hb,close);
            title.setOnMousePressed(event -> {
                lastTab =tabPane.showTab.get();
                tabPane.showTab(this);
                content.requestFocus();
            });
        }
        private void initDraga(){
//            为了显示被拖拽效果.
            ColorInput colorInput = new ColorInput();
            colorInput.setPaint(Color.rgb(216,229,245));
            colorInput.widthProperty().bind(title.widthProperty());
            colorInput.heightProperty().bind(title.heightProperty());
            title.setOnDragDetected(event -> {
                isDraga.set(true);
                oldTabPane = tabPane;
                title.startFullDrag();
                dragaTab = this;
                Dragboard db = title.startDragAndDrop(TransferMode.MOVE);
                ClipboardContent content = new ClipboardContent();
                content.putString("");
                db.setContent(content);
                db.setDragView(getTitleWritable());
                oldTabPane.titleLocationProperty.set(Location.DEFAULT);
//                当拖拽时show的tab.
                if (!oldTabPane.tabs.isEmpty()) {
//                    展示content
                    oldTabPane.content.getChildren().forEach(e -> e.setVisible(false));
                    oldTabPane.showTab .set (lastTab == null || lastTab == this ? oldTabPane.tabs.get(0) : lastTab);
                    oldTabPane.showTab.get().content.setVisible(true);
                    oldTabPane.showTab(oldTabPane.showTab.get());
                }
                title.setEffect(colorInput);
            });
            title.setOnDragEntered(event -> {
                FXBDTabPane.dragaOverTab = this;
                event.acceptTransferModes(TransferMode.ANY);
            });
            title.setOnDragExited(event -> {
                if (dragaTab == null) return;
                FXBDTabPane.dragaOverTab = null;
            });
            title.setOnDragOver(event -> {
                if (dragaTab == null) return;
                event.acceptTransferModes(TransferMode.ANY);
                FXBDTabPane.dragaOverTab.tabPane.titleLocationProperty.set(FXBDTabPane.dragaOverTab.getLocation(event.getSceneX()));
            });
            title.setOnDragDone(event -> {
                title.setEffect(null);
                if (tabPane.titleLocationProperty.get() != Location.NONE) {
                    oldTabPane.content.getChildren().remove(content);
                    tabPane.content.getChildren().add(content);
                    tabPane.showTab(dragaTab);
                }
                else if (dragaTabPane != null && dragaTabPane.contentLocationProperty.get() != Location.NONE) {
                    Location location = dragaTabPane.contentLocationProperty.get();
                    if (dragaTabPane == null)return;
                    oldTabPane.content.getChildren().remove(content);

                    if (location.equals(Location.CENTER)){
                        dragaTabPane.tabs.add(dragaTab);
                        dragaTab.setVisible(true);
                        dragaTabPane.refreshTitle();
                        dragaTabPane.content.getChildren().add(dragaTab.content);
                        dragaTab.tabPane = dragaTabPane;
                        dragaTabPane.showTab(dragaTab);
                    }
                    else {
                        FXBDTabPane fxbdTabPane = new FXBDTabPane();
                        fxbdTabPane.addTab(new FXBDTab(dragaTab,fxbdTabPane));
                        fxbdTabPane.refreshTitle();
                        SplitPane splitPane = new SplitPane(dragaTabPane.root.getItems().remove(0));
                        if (location.equals(Location.LEFT) || location.equals(Location.RIGHT)) {
                            dragaTabPane.root.setOrientation(Orientation.HORIZONTAL);
                            if (location.equals(Location.LEFT)) dragaTabPane.root.getItems().addAll(fxbdTabPane.root, splitPane);
                            else dragaTabPane.root.getItems().addAll(splitPane,fxbdTabPane.root );
                        }
                        else if (location.equals(Location.TOP) || location.equals(Location.BOTTOM)){
                            dragaTabPane.root.setOrientation(Orientation.VERTICAL);
                            if (location.equals(Location.TOP)) dragaTabPane.root.getItems().addAll(fxbdTabPane.root,
                                    splitPane);
                            else dragaTabPane.root.getItems().addAll(splitPane,fxbdTabPane.root );
                        }
                        dragaTabPane.root = splitPane;
                        roots.add(splitPane);
                    }
                } else {
                    Stage stage = new Stage();
                    stage.initOwner(tabPane.root.getScene().getWindow());
                    FXBDTabPane fxbdTabPane = new FXBDTabPane();
                    FXBDTab tab = new FXBDTab(dragaTab, fxbdTabPane);
                    tab.isDraga.addListener((ob,ov,nv)->{
                        if (!nv && fxbdTabPane.tabs.isEmpty()) stage.close();
                    });
                    fxbdTabPane.tabs.addListener((ob,ov,nv)->{
                        if (nv.isEmpty() && !tab.isDraga.get()){
                            stage.close();
                        }
                    });
                    fxbdTabPane.addTab(tab);
                    ContextMenu contextMenu = new ContextMenu();
                    fxbdTabPane.root.setContextMenu(contextMenu);
                    CheckMenuItem checkMenuItem = new CheckMenuItem("保持在最前面");
                    checkMenuItem.selectedProperty().addListener((ob,ov,nv)->stage.setAlwaysOnTop(nv));
                    contextMenu.getItems().add(checkMenuItem);
                    Scene scene = new Scene(fxbdTabPane.getTabPane());
                    scene.getStylesheets().add(Objects.requireNonNull(
                            Util.class.getResource("/css/FXBD.css")).toExternalForm());
                    stage.setScene(scene);
                    stage.show();
                    fxbdTabPane.refreshTitle();
                }
                if (oldTabPane.tabs.isEmpty()){
                    check(oldTabPane.root);
                }
                tabPane.contentLocationProperty.set(Location.NONE);
                if (dragaTabPane != null)dragaTabPane.contentLocationProperty.set(Location.NONE);
                dragaTab = null;
                FXBDTabPane.dragaOverTab = null;
                isDraga.set(false);
            });
        }
        public void addTooltip(String tooltip){

        }

    public boolean isShow() {
        return isShow.get();
    }

    public void setShow(boolean show) {
        isShow.set( show);
    }

    public WritableImage getTitleWritable(){
            WritableImage wi = new WritableImage((int) title.getWidth(), (int) title.getHeight());
            title.snapshot(new SnapshotParameters(),wi);
            return wi;
        }

        public ReadOnlyStringProperty getInfo() {
            return info;
        }
        public void setInfo(String info){
            this.info.set(info);
        }
        public double getWidth(){
            return title.getWidth();
        }
        public double getStartX(){
            return title.getLayoutX()-tabPane.tabsView.getPadding().getLeft();
        }
        public double getEndX(){
            return getStartX()+getWidth();
        }
        public Location getLocation(double x){
            x = x - title.getParent().localToScene(0,0).getX();
           double distance = getWidth()/2;
           double startX = getStartX();
           if ( x < startX +distance) return Location.LEFT;
           else if (x<startX +distance * 1.5)return Location.RIGHT;
           else return tabPane.titleLocationProperty.get();
        }
        public HBox getTitle() {
            return title;
        }
        public void setVisible(boolean visible){
            title.setVisible(visible);
        }}